package com.chenailin.www.service;

import com.chenailin.www.dao.AppointmentDAO;
import com.chenailin.www.dao.DoctorDAO;
import com.chenailin.www.daoimpl.AppointmentDAOImpl;
import com.chenailin.www.daoimpl.DoctorDAOImpl;
import com.chenailin.www.exception.ServiceException;
import com.chenailin.www.pojo.Appointment;
import com.chenailin.www.util.DateUtil;

import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

public class AppointmentService {
    private final AppointmentDAO appointmentDAO = new AppointmentDAOImpl();
    private final DoctorDAO doctorDAO = new DoctorDAOImpl();

    // 挂号功能 111
    public boolean createAppointment(Appointment appointment) throws IllegalStateException {
        // 验证时间段有效性
        if (!doctorDAO.isDoctorAvailable(appointment.getDoctorId(), appointment.getSchedule())) {
            throw new IllegalStateException("医生该时段不可预约");
        }
        // 检查是否重复预约
        if (appointmentDAO.hasConflict(appointment.getDoctorId(), appointment.getSchedule())) {
            throw new IllegalStateException("您在该时段已有其他预约");
        }
        try {
            // 验证是否成功
            return appointmentDAO.insertAppointment(appointment) && appointmentDAO.selectDoctor(appointment.getDoctorId(), appointment.getSchedule());
        } catch (SQLException e) { // 明确捕获SQL异常
            throw new ServiceException("数据库查询失败", e);
        }
    }

    // 是否通过身份验证
    public boolean isVerified(int userId) {
        return appointmentDAO.isVerified(userId);
    }

    // 查找挂号记录
    public List<Appointment> getUserAppointments(int userId) {
        return appointmentDAO.findByUserId(userId);
    }

    // 删除挂号记录
    public boolean cancelAppointment(int id) {
        try {
            if (!appointmentDAO.findByUserId(id).contains(appointmentDAO.findById(id))) {
                System.out.println("无效订单编号！");
                return false;
            }
            if (LocalDateTime.now().plusHours(2).isAfter(appointmentDAO.findById(id).getAppointmentTime().atStartOfDay())) {
                System.out.println("就诊前2小时内不可取消");
                return false;
            }
            return appointmentDAO.unSelectDoctor(appointmentDAO.findById(id).getDoctorId(), appointmentDAO.findById(id).getSchedule())
                    && appointmentDAO.deleteAppointment(id);
        } catch (SQLException e) { // 明确捕获SQL异常
            throw new ServiceException("数据库查询失败", e);
        }
    }

    // 显示可选日期
    public void showAvailableDates() {
        System.out.println("请选择预约日期：");
        Map<Integer, String> dates = DateUtil.generateWeekDates();
        dates.forEach((key, value) ->
                System.out.printf("%d. %s\n", key, value)
        );
    }

    // 标记医生为空闲
    public boolean unSelectDoctor(int id) {
        return appointmentDAO.unSelectDoctor(appointmentDAO.findById(id).getId(), appointmentDAO.findById(id).getSchedule());
    }

    // 标记医生为已选择
    public boolean selectDoctor(int id, int slot) {
        return appointmentDAO.selectDoctor(id, slot);
    }

    // 查找每日病人数量
    public int getDailyAppointments(int id, LocalDate date) {
        return appointmentDAO.getDailyAppointments(id, date);
    }

    // 判断id是否在预约号范围内
    public boolean ifIdExists(int id, List<Appointment> appointments) {
        return appointments.contains(appointmentDAO.findById(id));
    }

}